// demo-recv.cpp : Defines the entry point for the console application.
//

#include<gst/gst.h>
#define SEND_IP "172.29.41.43"

static gboolean
bus_call( GstBus *bus,GstMessage *msg, gpointer data )
{
	GMainLoop *loop = ( GMainLoop* )data;
	switch( GST_MESSAGE_TYPE( msg )) {
		case GST_MESSAGE_EOS:
					g_print ( "End-of-stream\n" );
					g_main_loop_quit( loop );
					break;
		case GST_MESSAGE_ERROR: {
					gchar *debug;
					GError* err;
					gst_message_parse_error( msg,&err,&debug );
					g_print ( "Error: %s\n", err ->message );
					g_error_free( err );
					g_main_loop_quit ( loop );
					break;
		}
		default:
					break;
	}
	return TRUE;
}

static void 
on_pad_added ( GstElement *element, GstPad *pad, gpointer data )
{
	GstPad *sinkpad;
	GstElement* elem = ( GstElement* ) data;
	g_print ( "Dynamic pad created, linking parser/decoder\n" );
	sinkpad = gst_element_get_pad( elem , "sink" );
	gst_pad_link ( pad, sinkpad );
	gst_object_unref( sinkpad );
}

int main(int argc, char* argv[])
{
	GstElement *pipeline, *udpsrc_rtp, *udpsrc_rtcp, *udpsink_rtcp;
	GstElement *rtpbin, *rtph264depay, *queue, *decoder, *sink;
	GstElement *filesink, *queuerecv,*queuesave, *tee;
	GMainLoop  *loop;
	gboolean ret =  FALSE;
	GstPad* srcpad;
	GstCaps* srccaps;
	gchar* name;
	char buff[1024];
	FILE* fp = NULL;
	int len = 0;
	

	gst_init (&argc, (char***)&argv);

	loop = g_main_loop_new( NULL,FALSE );

	pipeline      = gst_pipeline_new( "video-recv" );//dshowvideosrc
	udpsrc_rtp    = gst_element_factory_make ( "udpsrc", "udpsrc-rtp data" );
	udpsrc_rtcp   = gst_element_factory_make ( "udpsrc", "udpsrc-rtcp data" );
	udpsink_rtcp  = gst_element_factory_make ( "udpsink", "udpsink-rtcp" );
	rtpbin		    = gst_element_factory_make ( "gstrtpbin", "gstrtpbin" );
	rtph264depay  = gst_element_factory_make ( "rtph264depay", "rtph264depay" );
	queue		      = gst_element_factory_make ( "queue", "queue" );
	queuesave     = gst_element_factory_make ( "queue", "queuesave" );
	queuerecv		  = gst_element_factory_make ( "queue", "queuerecv" );
	decoder       = gst_element_factory_make ( "ffdec_h264", "decoder" );
	sink				  = gst_element_factory_make ( "autovideosink", "jpeg-output" );//directdrawsink
	filesink      = gst_element_factory_make ( "filesink", "filesink" );
	tee           = gst_element_factory_make ( "tee", "tee" );
	

	if( !pipeline || !udpsrc_rtp || !udpsrc_rtcp || !udpsink_rtcp ||
		!rtpbin || !rtph264depay || !queue || !decoder || !sink  || !filesink ) {
		g_print ( "One element could not be created \n" );
		return -1;
	}

	//g_object_set( G_OBJECT ( sink ), "location", "d:\\test.txt", NULL );
	//g_object_set( G_OBJECT ( udpsrc_rtp ),  "uri", "udp://localhost:4951", NULL );
	g_object_set( G_OBJECT ( filesink ), "location", "./test.txt", NULL );
	g_object_set( G_OBJECT ( udpsrc_rtp ),   "port", 10000, NULL );
	g_object_set( G_OBJECT ( udpsrc_rtcp ),  "port", 10001, NULL );
	g_object_set( G_OBJECT ( udpsink_rtcp ), "host", SEND_IP, NULL );
	g_object_set( G_OBJECT ( udpsink_rtcp ), "port", 10002, NULL );
	//g_object_set( G_OBJECT ( rtpbin ), "latency", 400 );

	/*srcpad = gst_element_get_pad( udpsrc_rtp, "src" );
	srccaps = gst_pad_get_caps( srcpad );
	name = gst_caps_to_string( srccaps );*/
	fp = fopen( "video.caps", "rb" );
	if( !fp ) {
		printf( "can't open video.caps\n" );
		return -1;
	}

	len = fread( buff, sizeof( char ), sizeof( buff ), fp );
	buff[0x108] = '\0';
	srccaps = gst_caps_from_string( buff );
	g_object_set( G_OBJECT ( udpsrc_rtp ), "caps", srccaps, NULL );

#if 1
	gst_bin_add_many( GST_BIN( pipeline ), udpsrc_rtp, udpsrc_rtcp, udpsink_rtcp,
		rtpbin, rtph264depay, queue, queuesave, queuerecv, tee, decoder, sink, filesink,NULL);

	ret = gst_element_link_pads_filtered( udpsrc_rtp, "src", rtpbin, "recv_rtp_sink_0", NULL );
	ret = gst_element_link_pads_filtered( udpsrc_rtcp, "src", rtpbin, "recv_rtcp_sink_0", NULL );
	ret = gst_element_link_pads_filtered( rtpbin, "send_rtcp_src_0", udpsink_rtcp, "sink", NULL );

	ret = g_signal_connect( rtpbin, "pad-added", G_CALLBACK( on_pad_added ), tee  );
	ret = gst_element_link_many( tee, queuesave, filesink, NULL );
	ret = gst_element_link_many( tee, rtph264depay, queue, decoder,  sink, NULL );
#else
	gst_bin_add_many( GST_BIN( pipeline ), udpsrc_rtp, queue, filesink, NULL );
	ret = gst_element_link_many( udpsrc_rtp, queue, filesink, NULL );
#endif

	g_print ( "Setting to recv video\n" );

	gst_element_set_state ( pipeline, GST_STATE_PLAYING );
	gst_element_set_locked_state( udpsink_rtcp, TRUE );
	g_main_loop_run( loop );

	g_print ( "returned ,stopping playback\n" );
	gst_element_set_state( pipeline, GST_STATE_NULL );
	g_print ( "Deleting pipeline\n" );
	gst_object_unref( GST_OBJECT ( pipeline ) );



	return 0;
}

